package com.dhcc.filter;

import com.dhcc.jwt.JwtTokenUtil;
import com.dhcc.props.AuthProperties;
import com.dhcc.provider.AuthProvider;
import io.jsonwebtoken.Claims;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * 自定义过滤器，用于动态添加请求头
 * @ProjectName Dhcc-Cloud
 * @PackageName com.dhcc.filter
 * @Title DynamicHeaderGatewayFilterFactory
 * @Date 2024/10/31 上午3:02
 * @Author LiuGuoting
 */
@Slf4j
@Component
public class DynamicHeaderGatewayFilterFactory extends AbstractGatewayFilterFactory<DynamicHeaderGatewayFilterFactory.Config> {

    private final AuthProperties authProperties;
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();
    public DynamicHeaderGatewayFilterFactory(AuthProperties authProperties) {
        super(Config.class);
        this.authProperties = authProperties;
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            // 获取请求路径
            String path = exchange.getRequest().getURI().getPath();
            // 判断是否跳过
            if (isSkip(path)) {
                if(antPathMatcher.match("/auth/**", path)){
                    // 添加自定义请求头
                    exchange.getRequest().mutate()
                            .header("X-Gateway-Header", "Auth") // 使用动态生成的值
                            .build();
                }else {
                    // 添加自定义请求头
                    exchange.getRequest().mutate()
                            .header("X-Gateway-Header", "Allow") // 使用动态生成的值
                            .build();
                }
                return chain.filter(exchange);
            }
            // 需要内部鉴权的接口，添加自定义请求头
            exchange.getRequest().mutate()
                    .header("X-Gateway-Header", "InternalRequest") // 使用动态生成的值
                    .build();
            // 继续处理请求
            return chain.filter(exchange);
        };
    }
    private boolean isSkip(String path) {
        return AuthProvider.getDefaultSkipUrl().stream().anyMatch(pattern -> antPathMatcher.match(pattern, path))
                || authProperties.getSkipUrl().stream().anyMatch(pattern -> antPathMatcher.match(pattern, path));
    }

    /**
     * 返回指定状态的 JSON 响应
     *
     * @param exchange  ServerWebExchange 对象
     * @param code      响应状态码
     * @param message   响应消息
     * @return Mono<Void> 用于表示响应的异步处理
     */
    private Mono<Void> jsonResponse(ServerWebExchange exchange, int code, String message) {
        // 获取响应对象
        ServerHttpResponse response = exchange.getResponse();

        // 设置响应状态
        response.setStatusCode(HttpStatus.valueOf(code));

        // 设置响应头，指定内容类型为 JSON 格式
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);

        // 构建响应内容
        String result = String.format("{\"code\": %d, \"message\": \"%s\"}", code, message);

        // 创建数据缓冲区并写入响应
        DataBufferFactory bufferFactory = response.bufferFactory();
        DataBuffer buffer = bufferFactory.wrap(result.getBytes(StandardCharsets.UTF_8));

        // 写入响应并结束
        return response.writeWith(Flux.just(buffer)).then(Mono.empty());
    }

    public static class Config {
        // 配置类可以保留，方便扩展
    }
}